import { Middleware } from '@midwayjs/decorator';
import { IMiddleware } from '@midwayjs/core';
import { NextFunction, Context } from '@midwayjs/koa';
import { UserService } from '../service/user.service';
import { LoginType } from '../interface/user.interface';
import { Unauthorized } from '../error/custom.error';
import { LoginFrequently } from '../error/custom.error';

const moment = require('moment');

@Middleware()
export class AntiBurstMiddleware implements IMiddleware<Context, NextFunction> {
  resolve() {
    return async (ctx: Context, next: NextFunction) => {
      const { username } = ctx.request.body as LoginType;
      const userService = await ctx.requestContext.getAsync<UserService>(
        UserService
      );
      const target = await userService.findUser(username);
      const timeDiff = moment().diff(moment(target.updateTime), 'minute');
      // 如果超过30分钟没登陆则把尝试次数归零
      if (timeDiff > 30) {
        await userService.changeUser(target, { try_count: 0 }); // 成功登录则归零尝试次数
      }
      // 15分钟内登录三次则禁止登录
      if (target.try_count >= 3 && timeDiff < 15) {
        throw new LoginFrequently();
      }
      const result = await next();
      if (!result?.error) {
        await userService.changeUser(target, { try_count: 0 }); // 成功登录则归零尝试次数
        return result;
      } else {
        await userService.changeUser(target, {
          try_count: target.try_count + 1, // 登录失败则尝试次数+1
        });
        throw new Unauthorized();
      }
    };
  }

  static getName(): string {
    return 'anti-burst';
  }
}
